/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023.
 * Description: support rtos madvise.
 * Author: heyuqiang <heyuqiang1@huawei.com>
 * Create: 2023-09-05
 * Note: this file isn't compiled independently, it is includded
 * in madvise.c
 */

#ifdef CONFIG_RTOS_MEM_MADV_COMMIT
static int madv_commit(struct vm_area_struct *vma,
				struct vm_area_struct **prev,
				unsigned long start, unsigned long end)
{
	int error;
	unsigned long new_flags;

	if (!can_madv_lru_vma(vma))
		return -EINVAL;

	new_flags = vma->vm_flags;
	new_flags |= (VM_READ | VM_WRITE);

	/*
	 * mprotect_fixup will set VM_ACCOUNT flag and add number of pages of
	 * this range to Commit_AS, so we just need to clear rtos_vm_flags.
	 */
	error = mprotect_fixup(vma, prev, start, end, new_flags);
	if (error)
		return error;

	return 0;
}

static int madv_decommit(struct vm_area_struct *vma,
				struct vm_area_struct **prev,
				unsigned long start, unsigned long end)
{
	int error;
	unsigned long new_flags;

	if (!can_madv_lru_vma(vma))
		return -EINVAL;

	if ((vma->vm_flags & (VM_READ | VM_WRITE)) != (VM_READ | VM_WRITE)) {
		*prev = vma;
		return 0;
	}

	new_flags = vma->vm_flags;
	new_flags &= ~(VM_READ | VM_WRITE | VM_ACCOUNT);

	error = madvise_dontneed_single_vma(vma, start, end);
	if (error)
		return error;

	error = mprotect_fixup(vma, prev, start, end, new_flags);
	if (error)
		return error;
	/*
	 * mprotect_fixup will not delete Commit_AS
	 */
	vm_unacct_memory((end - start) >> PAGE_SHIFT);

	return error;
}
#endif